/*
 * @Date: 2022-05-23 19:41:43
 * @LastEditors: sailornpg
 * @LastEditTime: 2022-05-24 11:20:56
 * @FilePath: \my-react-components\src\component\Upload\index.tsx
 * @Description: Upload
 */
import React, { ChangeEvent, memo, useRef, useState } from "react";
import axios from "axios";
import Button from "../Button";
import UploadList from "./UploadList";
export interface UploadProps {
  action: string;
  onProgress?: (percentage: number, file: File) => void;
  onSuccess?: (data: any, file: File) => void;
  onError?: (err: any, file: File) => void;
  beforeUpload?: (file: File) => boolean | Promise<File>;
  onChange?: (file: File) => void;
  defaultFileList?: UploadFile[];
  onRemove?: (file: UploadFile) => void;
}
export type UploadFileStatus = "ready" | "uploading" | "success" | "error";
export interface UploadFile {
  uid: string;
  size: number;
  name: string;
  status?: UploadFileStatus;
  percent?: number;
  raw?: File;
  response?: any;
  error?: any;
}
const Upload: React.FC<UploadProps> = memo(
  ({
    action,
    onError,
    onProgress,
    onSuccess,
    beforeUpload,
    onChange,
    defaultFileList,
    onRemove,
  }) => {
    const [fileList, setFileList] = useState<UploadFile[]>(
      defaultFileList || [],
    );
    const inputRef = useRef<HTMLInputElement>(null);
    const handleClick = () => {
      if (inputRef.current) {
        console.log(123);
        inputRef.current.click();
      }
    };
    const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
      const files = e.target.files;
      if (!files) {
        return;
      }
      uploadFile(files);
      if (inputRef.current) {
        inputRef.current.value = "";
      }
    };
    const updateFileList = (
      updateFile: UploadFile,
      updateObj: Partial<UploadFile>,
    ) => {
      setFileList((prevFileList) => {
        return prevFileList.map((file) => {
          if (file.uid === updateFile.uid) {
            return { ...file, ...updateObj };
          } else {
            return file;
          }
        });
      });
    };
    const post = (file: File) => {
      let _file: UploadFile = {
        uid: Date.now() + "upload_file",
        status: "ready",
        name: file.name,
        size: file.size,
        percent: 0,
        raw: file,
      };
      // setFileList([_file, ...fileList]);
      setFileList((prevList) => {
        return [_file, ...prevList];
      });
      const formData = new FormData();
      formData.append(file.name, file);
      axios
        .post(action, formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
          onUploadProgress: (e) => {
            let percentage = Math.round((e.loaded * 100) / e.total) || 0;
            if (percentage < 100) {
              updateFileList(_file, {
                percent: percentage,
                status: "uploading",
              });
              if (onProgress) {
                onProgress(percentage, file);
              }
            }
          },
        })
        .then((res) => {
          updateFileList(_file, {
            status: "success",
            response: res.data,
          });
          if (onSuccess) {
            onSuccess(res.data, file);
          }
          if (onChange) {
            onChange(file);
          }
        })
        .catch((err) => {
          updateFileList(_file, {
            status: "error",
            response: err,
          });
          if (onError) {
            onError(err, file);
          }
          if (onChange) {
            onChange(file);
          }
        });
    };
    const uploadFile = (files: FileList) => {
      let postFile = [...files];
      postFile.forEach((file) => {
        if (!beforeUpload) {
          post(file);
        } else {
          const res = beforeUpload(file);
          if (res && res instanceof Promise) {
            res.then((resFile) => {
              post(resFile);
            });
          } else if (res !== false) {
            post(file);
          }
        }
      });
    };
    return (
      <div className="sailor-upload-component">
        <Button btnType="primary" onClick={handleClick}>
          上传
        </Button>
        <input
          type="file"
          className="sailor-file-input"
          style={{ display: "none" }}
          ref={inputRef}
          onChange={handleFileChange}
        />
        <UploadList fileList={fileList} onRemove={(e) => {}}></UploadList>
      </div>
    );
  },
);

export default Upload;
